package com.fullertontech.framework.rabbitmq;

import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.Connection;

import com.rabbitmq.client.Channel;

public class RabbitClient {
	private CachingConnectionFactory connectionFactory;
	protected void setConnectionFactory(CachingConnectionFactory connectionFactory) {
		this.connectionFactory=connectionFactory;
	}
	Connection getConnection() {
		return connectionFactory.createConnection();
	}
	Channel getChannel(Connection connection) {
		return connection.createChannel(false);
	}
	Channel getChannel() {
		return getConnection().createChannel(false);
	}
	
	void closeConnection(Channel channel) throws Exception{
		try {
			if(channel!=null&&channel.isOpen()) {
				channel.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally {//connection是单例的，不能关闭
			/*if(channel!=null&&channel.getConnection()!=null&&channel.getConnection().isOpen()) {
				try {
					channel.getConnection().close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}*/
		}
	}
	
	/*public void sendFanoutQueue(String queue,String exchange,String message) throws Exception {
		sendQueue(queue, exchange, ExchangeTypes.FANOUT, message);
	}
	
	public void sendTopicQueue(String queue,String exchange,String message) throws Exception {
		sendQueue(queue, exchange, ExchangeTypes.TOPIC, message);
	}*/
	
	public void sendMsg(String queue,String message) throws Exception {
		sendDirectQueue(queue, queue, message);
	}
	public void sendMsg(String queue,String exchange,String message) throws Exception {
		sendDirectQueue(queue, exchange, message);
	}
	
	private void sendDirectQueue(String queue,String exchange,String message) throws Exception {
		sendQueue(queue, exchange, ExchangeTypes.DIRECT, message);
	}
	
	/*public void sendHeadersQueue(String queue,String exchange,String message) throws Exception {
		sendQueue(queue, exchange, ExchangeTypes.HEADERS, message);
	}
	
	public void sendSystemQueue(String queue,String exchange,String message) throws Exception {
		sendQueue(queue, exchange, ExchangeTypes.SYSTEM, message);
	}*/
	
	void createBindQueue(String queue,String exchange,ExchangeTypes exchangeTypes) throws Exception {
		final Channel channel=getChannel();
		try {
			//创建交换机
			try {
				channel.exchangeDeclare(exchange, exchangeTypes.toString(), true, false, null);
			} catch (Exception e) {
				// TODO: handle exception
			}
			//创建队列
			try {
				//创建队列失败可能是之前已经存在的
				channel.queueDeclare(queue, true, false, false, null);
			} catch (Exception e) {
				// TODO: handle exception
			}
			//绑定队列到交换机
			channel.queueBind(queue, exchange, queue);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}finally {
			closeConnection(channel);
		}
	}
	
	private void sendQueue(String queue,String exchange,ExchangeTypes exchangeTypes,String message) throws Exception{
		final Channel channel=getChannel();
		try {
			//创建交换机
			try {
				//创建队列失败可能是之前已经存在的
				channel.exchangeDeclare(exchange, exchangeTypes.toString(), true, false, null);
			} catch (Exception e) {
				// TODO: handle exception
			}
			//创建队列
			try {
				//创建队列失败可能是之前已经存在的
				channel.queueDeclare(queue, true, false, false, null);
			} catch (Exception e) {
				// TODO: handle exception
			}
			//绑定队列到交换机
			channel.queueBind(queue, exchange, queue);
			//发送消息
			channel.basicPublish(exchange, queue, null, message.getBytes());
		} catch (Exception e) {
			throw new RuntimeException(e);
		}finally {
			closeConnection(channel);
		}
	}
}
